package main

import (
	"encoding/json"
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
)

// 患者病历ID、主诉等信息（患者自述自己的症状或体征、性质，以及持续时间等内容）
type ComplaintInfo struct {
	// 患者该条病历的id
	IdNumber string `json:"idNumber"`
	// 患者身份证号
	IdCardNumber string `json:"idCardNumber"`
	// 是否能够修改病历
	AllowModify string `json:"allowModify"`
	// 是否能够删除病历
	AllowDelete string `json:"allowDelete"`
	// 该条病历的创建时间
	MedicalCreateTime string `json:"medicalCreateTime"`
	// 患者疾病类型
	MedicalType string `json:"medicalType"`
	// 患者主诉
	MainSymptoms string `json:"mainSymptoms"`
	// 此条病历的私钥信息
	PrivateKey string `json:"privateKey"`
	// 此条病历的公钥信息
	PublicKey string `json:"publicKey"`
	// 患者曾患病
	DiseasesOnceSuffered string `json:"diseasesOnceSuffered"`

	// 患者症状详细信息
	// 发病时间和可能的病因
	OnsetTimeAndPossiblePathogeny string `json:"onsetTimeAndPossiblePathogeny"`
	// 主要症状的详细描述
	MainSymptomsElaborateDescription string `json:"mainSymptomsElaborateDescription"`
	// 伴随症状
	SimultaneousPhenomenon string `json:"simultaneousPhenomenon"`
	// 患者患有的其他疾病
	OtherDiseases string `json:"otherDiseases"`
	// 发病以来的一般情况
	GeneralConditions string `json:"generalConditions"`
	// 图片描述
	ImageUrl string `json:"imageUrl"`

	// 患者个人历史信息
	// 患者最近去过的地点以及时间
	RecentAreaAndDate string `json:"recentAreaAndDate"`
	// 患者起居习惯、卫生习惯、饮食规律
	HabitsAndCustoms string `json:"habitsAndCustoms"`
	// 患者的职业和工作环境
	Occupation string `json:"occupation"`
	// 患者有无冶游史，以及发生时间
	VisitProstitutes string `json:"visitProstitutes"`
	// 患者生长发育史
	GrowthAndDevelopmentHistory string `json:"growthAndDevelopmentHistory"`
	// 患者婚姻情况
	MaritalStatus string `json:"maritalStatus"`
	// 女性患者月经情况
	Menstruation string `json:"menstruation"`
	// 患者生殖健康情况
	ReproductionCondition string `json:"reproductionCondition"`
}

type resultData struct {
	RecordInfos []ComplaintInfo `json:"recordInfos"`
}

func (r *ComplaintInfo) Init(stub shim.ChaincodeStubInterface) pb.Response {
	return shim.Success(nil)
}

func (r *ComplaintInfo) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	funcName, args := stub.GetFunctionAndParameters()
	if funcName == "save" {
		return r.saveRecord(stub, args)
	} else if funcName == "query" {
		return r.queryRecord(stub, args)
	} else if funcName == "queryHistory" {
		return r.queryHistoryRecord(stub, args)
	} else {
		return shim.Error("no such function")
	}
}

func (r *ComplaintInfo) saveRecord(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 2 {
		return shim.Error("except two args")
	} else {
		err := stub.PutState(args[0], []byte(args[1]))
		if err != nil {
			return shim.Error(err.Error())
		}
		return shim.Success(nil)
	}

}

func (r *ComplaintInfo) queryRecord(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 1 {
		return shim.Error("except one arg")
	} else {
		value, err := stub.GetState(args[0])
		if err != nil {
			shim.Error("no data found")
		}
		return shim.Success(value)
	}
}

func (r *ComplaintInfo) queryHistoryRecord(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	if len(args) != 1 {
		return shim.Error("except one arg")
	} else {
		//queryParam :="{\"selector\":{\"identity\":\""+id+"\"}}"
		recordinfos := []ComplaintInfo{}
		it, err := stub.GetHistoryForKey(args[0])
		if err != nil {
			return shim.Error("no data found")
		} else {
			fmt.Println("is data exits?", it.HasNext())
			for it.HasNext() {
				keym, err := it.Next()
				if err != nil {
					return shim.Error("data get error")
				}
				value := keym.Value
				fmt.Println("get value is", string(value))
				recordinfo := new(ComplaintInfo)
				json.Unmarshal(value, &recordinfo)
				fmt.Println("recordinfo is ", recordinfo)
				recordinfos = append(recordinfos, *recordinfo)
				fmt.Println("recordinfos is ", recordinfos)
			}
			resultdata := new(resultData)
			resultdata.RecordInfos = recordinfos
			fmt.Println("resultdata is ", resultdata)
			value, err := json.Marshal(resultdata)
			if err != nil {
				shim.Error(err.Error())
			}
			return shim.Success(value)
		}
	}
}

func main() {
	err := shim.Start(new(ComplaintInfo))
	if err != nil {
		fmt.Println("emr ComplaintInfo chaincode start error")
	}
}
